# -*- coding: utf-8 -*-
import pygame
import sys
import numpy as np
import random
from pygame.locals import *

# 初始化
pygame.init()
print(type([6, 7, 8]))
# 常量定义
BOARD_SIZE = 15  # 15x15的棋盘
GRID_SIZE = 40  # 每个格子的像素大小
PIECE_RADIUS = 18  # 棋子半径
MARGIN = 80  # 棋盘边距
WIDTH = BOARD_SIZE * GRID_SIZE + 2 * MARGIN  # 窗口宽度
HEIGHT = BOARD_SIZE * GRID_SIZE + 2 * MARGIN  # 窗口高度
FPS = 30  # 帧率

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BOARD_COLOR = (220, 179, 92)  # 棋盘颜色
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)

# 创建窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('五子棋人机对战')
clock = pygame.time.Clock()

# 初始化棋盘 (0:空, 1:黑子, 2:白子)
sub_shape = (2,)
board = [[[0, 0] for _ in range(15)] for _ in range(15)]

# 当前玩家 (1:黑棋玩家, 2:白棋AI)
current_player = 1
game_over = False
winner = None

# 加载字体
# 设置中文字体（替换为你的字体路径）
font_path = "/System/Library/Fonts/STHeiti Light.ttc"  # macOS 下的苹方字体
try:
    font = pygame.font.Font(font_path, 12)  # 自定义字体文件
except:
    font = pygame.font.SysFont("SimHei", 12)  # 回退到系统字体


def draw_board():
    """绘制棋盘"""
    screen.fill(BOARD_COLOR)

    # 绘制网格线
    for i in range(BOARD_SIZE):
        # 横线
        pygame.draw.line(screen, BLACK,
                         (MARGIN, MARGIN + i * GRID_SIZE),
                         (MARGIN + (BOARD_SIZE - 1) * GRID_SIZE, MARGIN + i * GRID_SIZE), 2)
        col_surface = font.render(str(i), True, BLACK)
        screen.blit(col_surface, (MARGIN - 30, MARGIN + i * GRID_SIZE - 10))
        # 竖线
        pygame.draw.line(screen, BLACK,
                         (MARGIN + i * GRID_SIZE, MARGIN),
                         (MARGIN + i * GRID_SIZE, MARGIN + (BOARD_SIZE - 1) * GRID_SIZE), 2)
        text_surface = font.render(str(i), True, BLACK)
        screen.blit(text_surface, (MARGIN + i * GRID_SIZE - 10, MARGIN - 30))
    # 绘制五个小黑点(天元、星位)
    dots = [(3, 3), (3, 11), (7, 7), (11, 3), (11, 11)]
    for dot in dots:
        pygame.draw.circle(screen, BLACK,
                           (MARGIN + dot[0] * GRID_SIZE, MARGIN + dot[1] * GRID_SIZE), 5)

    # 绘制棋子
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if board[i][j][0] == 1:  # 黑棋
                pygame.draw.circle(screen, BLACK,
                                   (MARGIN + i * GRID_SIZE, MARGIN + j * GRID_SIZE), PIECE_RADIUS)
            elif board[i][j][0] == 2:  # 白棋
                pygame.draw.circle(screen, WHITE,
                                   (MARGIN + i * GRID_SIZE, MARGIN + j * GRID_SIZE), PIECE_RADIUS)
                pygame.draw.circle(screen, BLACK,
                                   (MARGIN + i * GRID_SIZE, MARGIN + j * GRID_SIZE), PIECE_RADIUS, 1)
            text_score = font.render(str(board[i][j][1]), True, RED)
            screen.blit(text_score, (MARGIN + i * GRID_SIZE, MARGIN + j * GRID_SIZE))
    # 显示当前玩家
    status_text = "当前: 黑棋(玩家)" if current_player == 1 else "白棋(AI)"
    if game_over:
        if winner:
            status_text = "黑棋(玩家)" if winner == 1 else "白棋(AI) 获胜! 点击重新开始"
        else:
            status_text = "平局! 点击重新开始"

    text_surface = font.render(status_text, True, BLACK)
    screen.blit(text_surface, (10, 10))

    pygame.display.flip()


def get_board_position(mouse_pos):
    """将鼠标位置转换为棋盘坐标"""
    x, y = mouse_pos
    if (x < MARGIN or x > WIDTH - MARGIN or
            y < MARGIN or y > HEIGHT - MARGIN):
        return None

    col = round((x - MARGIN) / GRID_SIZE)
    row = round((y - MARGIN) / GRID_SIZE)

    # 确保坐标在棋盘范围内
    col = max(0, min(col, BOARD_SIZE - 1))
    row = max(0, min(row, BOARD_SIZE - 1))

    return col, row


def is_valid_move(col, row):
    """检查落子是否有效"""
    return board[col][row][0] == 0


def make_move(col, row, player):
    """在指定位置落子"""
    board[col][row][0] = player


def check_winner(col, row, player):
    """检查是否有玩家获胜"""
    # 四个方向: 水平, 垂直, 主对角线, 副对角线
    directions = [(1, 0), (0, 1), (1, 1), (1, -1)]

    for dx, dy in directions:
        count = 1  # 当前棋子

        # 正向检查
        x, y = col + dx, row + dy
        while 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and board[x][y][0] == player:
            count += 1
            x += dx
            y += dy

        # 反向检查
        x, y = col - dx, row - dy
        while 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and board[x][y][0] == player:
            count += 1
            x -= dx
            y -= dy

        if count >= 5:
            return True

    return False


def evaluate_position(board, player):
    """评估当前棋盘对指定玩家的有利程度"""
    opponent = 3 - player  # 对手
    score = 0

    # 定义棋型分数
    patterns = {
        # 活四: 连续4个己方棋子且两端空
        "live_four": 100000,
        # 冲四: 连续4个己方棋子且一端被阻挡
        "blocked_four": 10000,
        # 活三: 连续3个己方棋子且两端空
        "live_three": 1000,
        # 眠三: 连续3个己方棋子且一端被阻挡
        "blocked_three": 100,
        # 活二: 连续2个己方棋子且两端空
        "live_two": 10,
        # 其他情况
        "other": 1
    }

    # 检查所有方向
    directions = [(1, 0), (0, 1), (1, 1), (1, -1)]

    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if board[i][j][0] == player:
                for dx, dy in directions:
                    # 检查连续棋子
                    count = 1
                    blocked = False
                    blocked2 = False
                    x, y = i + dx, j + dy

                    if x < 0 or x >= BOARD_SIZE or y < 0 or y >= BOARD_SIZE or board[x][y][0] == opponent:
                        blocked = True
                    step = 0
                    space = 0
                    while 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and (board[x][y][0] == player or board[x][y][0] == 0) and step < 6 and space <2 :
                        if board[x][y][0] == player:
                            count += 1
                        step += 1
                        space += 1
                        x += dx
                        y += dy

                    if x < 0 or x >= BOARD_SIZE or y < 0 or y >= BOARD_SIZE or board[x][y][0] == opponent:
                        blocked = True

                    x_o, y_o = i - dx, j - dy
                    if x_o < 0 or x_o >= BOARD_SIZE or y < 0 or y_o >= BOARD_SIZE or board[x_o][y_o][0] == opponent:
                        blocked2 = True
                    step = 0
                    space = 0
                    while 0 <= x_o < BOARD_SIZE and 0 <= y_o < BOARD_SIZE and (board[x_o][y_o][0] == player or board[x_o][y_o][0] == 0) and step < 6 and space < 2:
                        if board[x_o][y_o][0] == player:
                            count += 1
                        step += 1
                        space +=1
                        x_o -= dx
                        y_o -= dy

                    if x_o < 0 or x_o >= BOARD_SIZE or y < 0 or y_o >= BOARD_SIZE or board[x_o][y_o][0] == opponent:
                        blocked2 = True

                    # 根据棋型加分
                    if count == 4:
                        if not blocked and not blocked2:
                            score += patterns["live_four"]
                        elif blocked or blocked2:
                            score += patterns["blocked_four"]
                    elif count == 3:
                        if not blocked and not blocked2:
                            score += patterns["live_three"]
                        elif blocked or blocked2:
                            score += patterns["blocked_three"]
                    elif count == 2:
                        if not blocked and not blocked2:
                            score += patterns["live_two"]
                        elif blocked or blocked2:
                            score += patterns["other"]
                    elif count >= 5:
                        score += patterns["live_four"] * 2  # 长连额外加分
    return score


def ai_move():
    """AI选择最佳落子位置"""
    best_score = -float('inf')
    best_move = None

    # 遍历所有可能的位置
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if board[i][j][0] == 0:  # 空位
                # 模拟落子
                board[i][j][0] = 2  # AI是白棋(2)

                # 检查是否能直接获胜
                if check_winner(i, j, 2):
                    board[i][j][0] = 0  # 撤销模拟
                    return i, j

                # # # 评估这个位置
                ai_score = evaluate_position(board, 2)
                print("ai==>", ai_score)

                # 如果这个位置能阻止玩家获胜，增加权重
                board[i][j][0] = 1  # 模拟玩家落子
                if check_winner(i, j, 1):
                    score += 50000  # 阻止玩家获胜很重要
                    return i, j
                score = evaluate_position(board, 1)
                print("you ==>", score)
                if ai_score > score:
                    score = ai_score
                #
                # # # 中心位置有优势
                center_x, center_y = BOARD_SIZE // 2, BOARD_SIZE // 2
                distance_to_center = abs(i - center_x) + abs(j - center_y)
                score += (BOARD_SIZE - distance_to_center) * 2
                #
                # # 随机性，避免每次都一样
                # score += random.randint(0, 10)

                # 撤销模拟落子
                board[i][j][0] = 0
                board[i][j][1] = score


                if score > best_score:
                    best_score = score
                    best_move = (i, j)

    return best_move


def reset_game():
    """重置游戏"""
    global board, current_player, game_over, winner
    board = [[[0, 0] for _ in range(15)] for _ in range(15)]
    current_player = 1
    game_over = False
    winner = None


# 主游戏循环
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        if event.type == MOUSEBUTTONDOWN and event.button == 1:  # 左键点击
            if game_over:
                reset_game()
            elif current_player == 1:  # 玩家回合
                pos = get_board_position(event.pos)
                if pos:
                    col, row = pos
                    if is_valid_move(col, row):
                        make_move(col, row, current_player)

                        # 检查是否获胜
                        if check_winner(col, row, current_player):
                            game_over = True
                            winner = current_player
                        elif not (sublist[0] == 0 for row in board for sublist in row):  # 棋盘已满
                            game_over = True
                        else:
                            current_player = 3 - current_player  # 切换玩家

    # AI回合
    if not game_over and current_player == 2:
        # 添加延迟，使AI落子可见
        pygame.time.delay(500)
        col, row = ai_move()
        make_move(col, row, current_player)

        # 检查是否获胜
        if check_winner(col, row, current_player):
            game_over = True
            winner = current_player
        elif not (sublist[0] == 0 for row in board for sublist in row):  # 棋盘已满
            game_over = True
        else:
            current_player = 3 - current_player  # 切换玩家

    draw_board()
    clock.tick(FPS)
